package edu.nf.ch11.pool;

import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.util.LinkedHashSet;

/**
 * @author wangl
 * @date 2025/4/18
 * 连接池
 */
public class ConnectionPool {

    /**
     * 连接池
     */
    private LinkedHashSet<Connection> pool = new LinkedHashSet<>();

    /**
     * 构造方法初始化池
     * @param initSize
     */
    public ConnectionPool(int initSize) {
        for (int i = 0; i < initSize; i++) {
            //从数据库获取一个连接
            Connection conn = ConnUtils.getConnection();
            //为这个连接创建一个代理
            conn = createProxy(conn);
            //将代理对象放入到池中
            pool.add(conn);
        }
    }

    /**
     * 创建代理
     * @param conn
     * @return
     */
    private Connection createProxy(Connection conn) {
        //获取类加载器
        ClassLoader loader = ConnectionPool.class.getClassLoader();
        //目标对象实现的接口
        Class<?>[] interfaces = new Class[]{Connection.class};
        //匿名实现一个InvocationHandler并创建代理实例
        return (Connection) Proxy.newProxyInstance(loader, interfaces, (proxy, method, args) -> {
            //如果当前调用的是close方法，就将这个连接放回连接池
            if("close".equals(method.getName())) {
                //注意：强转为Connection接口
                pool.addLast((Connection) proxy);
                return null;
            }
            //除了close以外的其他方法都正常调用，不需要代理
            return method.invoke(conn, args);
        });
    }

    /**
     * 连接池大小
     * @return
     */
    public int size() {
        return pool.size();
    }

    /**
     * 从连接池获取连接
     * @return
     */
    public Connection getConnection(){
        return pool.removeFirst();
    }
}